/*
 * message.c
 *
 *  Created on: 11-nov-2009
 *      Author: pablo
 */

//lib genericas
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

//clases propias
#include "message.h"
//#include "listas.h"
//#include "conexion.h"
//#include "constantes.h"
// #include "MODULO DE FRANCISCO DE SOCKETS"

/* trata de preparar y enviar la cabecera, devuelve
 * 0.- no se pudo preparar
 * 1.- Se envio correctamente
 */
int prepararCabecera(int soc, struct messageHeader *cabecera){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'prepararCabecera() de mensajes.c --\n");
	//return 1;
#endif
	ssize_t esc=-1;
	esc=enviar(soc,cabecera->GUID,  LENGTH_MESSAGE_ID);
	if (esc  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-fin en 'prepararCabecera() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	esc=enviar(soc,cabecera->payload_type,  LENGTH_PAYLOAD_TYPE);
	if (esc  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-fin en 'prepararCabecera() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	esc=enviar(soc, (char *)&cabecera->ttl, LENGTH_TTL);
	if (esc  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -3-fin en 'prepararCabecera() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	esc=enviar(soc,(char *)&cabecera->hops, LENGTH_HOPS);
	if (esc  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -4-fin en 'prepararCabecera() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	esc=enviar(soc,(char *)&cabecera->payload_length, LENGTH_PAYLOAD_LENGTH );
	if (esc  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -5-fin en 'prepararCabecera() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -6-fin en 'prepararCabecera() de mensajes.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}



/* Lee la cabecera pasada, convierte el chorro de bytes que tiene
 * el socket a una estructura facil de entender
 *
 * devuelve:
 *  0.- encaso de error
 *  1.- en caso de acabar bien
 * */
int leerCabecera(int soc, struct messageHeader *cabecera){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'leerCabecera() de mensajes.c --\n");
	//return 1;
#endif
	unsigned char GUID[LENGTH_MESSAGE_ID];
	unsigned char payload_type;
	unsigned char ttl;
	unsigned char hops;
	unsigned int length_payload;
	bzero(GUID,LENGTH_MESSAGE_ID);
	int leido;

	if ((leido=recibir(soc, GUID, LENGTH_MESSAGE_ID)) <= 0){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-fin en 'leerCabecera() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	memcpy(cabecera->GUID, GUID, LENGTH_MESSAGE_ID);

	if ((leido=recibir(soc, (char *)&payload_type, LENGTH_PAYLOAD_TYPE)) <= 0){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-fin en 'leerCabecera() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	cabecera->payload_type = payload_type;

	if ((leido = recibir(soc, (char *)&ttl, LENGTH_TTL)) <= 0){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -3-fin en 'leerCabecera() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
}
	cabecera->ttl = ttl;

	if ((leido = recibir(soc, (char *)&hops, LENGTH_HOPS)) <= 0){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -4-fin en 'leerCabecera() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	cabecera->hops = hops;

	if ((leido = recibir(soc, (char *)&length_payload, LENGTH_PAYLOAD_LENGTH)) <= 0){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -5-fin en 'leerCabecera() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	cabecera->payload_length = length_payload;
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -6-fin en 'leerCabecera() de mensajes.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int prepararQuery(int soc, struct queryMessage *consulta){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'prepararQuery() de mensajes.c --\n");
	//return 1;
#endif
	ssize_t escrito;
	escrito=enviar(soc, (char *)&consulta->min_speed, LENGTH_MINIMUM_SPEED);
	if(escrito<=0){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-fin en 'prepararQuery() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	escrito=enviar(soc, consulta->search, strlen(consulta->search)+1);
	if(escrito<=0){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -5-fin en 'prepararQuery() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -5-fin en 'prepararQuery() de mensajes.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}


int leerQuery(int soc, struct queryMessage *consulta, size_t resto){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'leerQuery() de mensajes.c --\n");
	//return 1;
#endif
	char *p;
	ssize_t n;
	int sal;
	unsigned short int minVel;
	consulta->search = malloc (resto-LENGTH_MINIMUM_SPEED);
	n=recibir(soc, (char *)&minVel,LENGTH_MINIMUM_SPEED);
	if ( n > 0 ){
		consulta->min_speed = minVel;
		p = (char *)consulta->search;
		n=recibir(soc, p, resto-LENGTH_MINIMUM_SPEED);
		if (n  <= 0 )
			sal = B_FALSE;
	}else{
		sal = B_FALSE;
	}
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-fin en 'leerQuery() de mensajes.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}

int prepararQueryHit(int soc, struct queryHitMessage *exito){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'prepararQueryHit() de mensajes.c --\n");
	//return 1;
#endif
	ssize_t n;
	int i = 0;
	int env = B_TRUE;
	struct resultSet *s;
	n=enviar(soc,  (char *)&exito->numExitos, LENGTH_NUMBER_OF_HITS);
	if (n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-fin en 'prepararQueryHit() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	n=enviar(soc, (char *)&exito->port, LENGTH_PORT);
	if (n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-fin en 'prepararQueryHit() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	n=enviar(soc, (char *)&exito->ip, LENGTH_IP);
	if (n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -3-fin en 'prepararQueryHit() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	n=enviar(soc, (char *)&exito->speed, LENGTH_SPEED);
	if (n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -4-fin en 'prepararQueryHit() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	s = exito->result;
	while(env==B_TRUE && i<exito->numExitos && s!=NULL){
		env = prepararResultSet(soc,s);
		s = s->next;
		i++;
	}
	n=enviar(soc, (char *)&exito->serventID, LENGTH_MESSAGE_ID);
	if (n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -5-fin en 'prepararQueryHit() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -6-fin en 'prepararQueryHit() de mensajes.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}


int leerQueryHit(int soc, struct queryHitMessage *exito, size_t resto){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'leerQueryHit() de mensajes.c --\n");
	//return 1;
#endif
	ssize_t n;
	unsigned char numExitos;
	in_port_t port;
	in_addr_t ip;
	unsigned int vel;
	struct resultSet *s;
	int i = 0;
	unsigned char serventID[LENGTH_MESSAGE_ID];
	n=recibir(soc, (char *)&numExitos, LENGTH_NUMBER_OF_HITS);
	if (n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-fin en 'leerQueryHit() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	exito->numExitos = numExitos;
	n=recibir(soc, (char *)&port, LENGTH_PORT);
	if ( n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-fin en 'leerQueryHit() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	exito->port = port;
	n=recibir(soc, (char *)&ip, LENGTH_IP);
	if ( n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -3-fin en 'leerQueryHit() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	exito->ip = ip;
	n=recibir(soc, (char *)&vel, LENGTH_SPEED);
	if (n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -4-fin en 'leerQueryHit() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	exito->speed = vel;
	exito->result = NULL;
	// los result set
	resto = resto - LENGTH_NUMBER_OF_HITS - LENGTH_PORT - LENGTH_IP - LENGTH_SPEED;
	for ( i = 0; i < exito->numExitos && resto > 0; i++){
		if( i == 0 ){
			exito->result = malloc (sizeof (struct resultSet));
			s = exito->result;
		}else{
			s->next = malloc (sizeof (struct resultSet));
			s = s->next;
		}
		leerResultSet (soc, s, resto);
		resto = resto - LENGTH_FILE_SIZE - strlen (s->indiceArchivo) - strlen (s->nombreArchivo);
		s->next = NULL;
	}
	n=recibir(soc, serventID, LENGTH_MESSAGE_ID);
	if (n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -5-fin en 'leerQueryHit() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	memcpy(exito->serventID, serventID, LENGTH_MESSAGE_ID);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -6-fin en 'leerQueryHit() de mensajes.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int prepararResultSet ( int soc, struct resultSet *s){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'prepararResultSet() de mensajes.c --\n");
	//return 1;
#endif
	ssize_t n;
	n=enviar(soc, (char *)&s->tamArchivo, LENGTH_FILE_SIZE);
	if (n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-fin en 'prepararResultSet() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	n=enviar(soc, (char *)s->indiceArchivo, strlen(s->indiceArchivo)+1);
	if (n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-fin en 'prepararResultSet() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	n=enviar(soc, (char *)s->nombreArchivo, strlen(s->nombreArchivo)+1);
	if (n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -3-fin en 'prepararResultSet() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -4-fin en 'prepararResultSet() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
	return B_TRUE;
}
int leerResultSet ( int soc, struct resultSet *s, size_t n){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'leerResultSet() de mensajes.c --\n");
	//return 1;
#endif
	/*
	 * unsigned int tamArchivo; //para permitir mayor tamaño, xq siempre >0
		char *indiceArchivo;  // indizacion del archivo
		char *nombreArchivo; //nombre del archivo
		struct resultSet *next;
	 */
	ssize_t leido;
	unsigned int tamArchivo;
	leido=recibir(soc, (char *)&tamArchivo, LENGTH_FILE_SIZE);
	if (leido  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-fin en 'leerResultSet() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	s->indiceArchivo = recibirCadena(soc, n,'\0');
	s->indiceArchivo = recibirCadena(soc, n,'\0');
	s->tamArchivo = tamArchivo;
	s->next = NULL;
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-fin en 'leerResultSet() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
	return B_TRUE;
}

int enviarMensaje (int soc, struct message *m){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'leerResultSet() de mensajes.c --\n");
	//return 1;
#endif
	size_t n;
	struct messageHeader *c;
	int sal;
	c = m->header;
	sal = prepararCabecera(soc, c );
	if (sal != B_FALSE && c->payload_type == PAYLOAD_QUERY ){
		n = c->payload_length;
		sal = prepararQuery(soc,((struct queryMessage *)c->payload));
	}else if (sal != B_FALSE && c->payload_type == PAYLOAD_QUERY_HIT){
		n = c->payload_length;
		sal = prepararQueryHit(soc, ((struct queryHitMessage *)c->payload));
	}else if (sal != B_FALSE && c->payload_type == PAYLOAD_BYE){
		n = c->payload_length;
		sal = prepararBye( soc, ((struct byeMessage *)c->payload) );
	}
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-fin en 'leerResultSet() de mensajes.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}


struct message * recibirMensaje (int soc){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'leerResultSet() de mensajes.c --\n");
	//return 1;
#endif
	size_t n;
	struct message *sal;
	struct messageHeader *c;
	struct queryMessage *q;
	struct queryHitMessage *h;
	struct byeMessage *b;

	sal = (struct message *) malloc ( sizeof (struct message) );
	sal->sockfd = soc;
	c = malloc (sizeof (struct messageHeader));
	if( leerCabecera ( soc, c ) == B_FALSE ) {
		if( c ) free( c );
		if( sal ) free( sal );
		return NULL;
	}
	sal->header = c;
	if (c->payload_type == PAYLOAD_QUERY ){
		n = sal->header->payload_length;
		q = malloc (sizeof (struct queryMessage));
		if( leerQuery(soc, q, n) == B_FALSE ) {
			if( q ) free( q );
			if( c ) free( c );
			if( sal ) free( sal );
			return NULL;
		}
		sal->header->payload = q;
	} else if (c->payload_type == PAYLOAD_QUERY_HIT) {
		n = c->payload_length;
		h = malloc (sizeof (struct queryHitMessage));
		if (leerQueryHit(soc, h, n) == B_FALSE){
			if( h ) free( h );
			if( c ) free( c );
			if( sal ) free( sal );
			return NULL;
		}
		sal->header->payload = h;
	} else if (c->payload_type == PAYLOAD_BYE){
		n = c->payload_length;
		b = malloc (sizeof (struct byeMessage));
		if (leerBye( soc, b, n) == B_FALSE){

			if( b ) free( b );
			if( c ) free( c );
			if( sal ) free( sal );
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-fin en 'leerResultSet() de mensajes.c, salida=NULL --\n");
	//return 1;
#endif
			return NULL;
		}
		printf("%s\n",b->description);
		sal->header->payload = b;
	}else{
		free ( c );
		free ( sal );
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-fin en 'leerResultSet() de mensajes.c, salida=NULL --\n");
	//return 1;
#endif
		return NULL;
	}
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -3-fin en 'leerResultSet() de mensajes.c, salida=estructura de Mensaje --\n");
	//return 1;
#endif
	return sal;
}

int prepararBye(int soc, struct byeMessage *b){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'prepararBye() de mensajes.c --\n");
	//return 1;
#endif
	ssize_t n;
	n=enviar(soc, b->code, LENGTH_BYE_CODE);
	if (n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-fin en 'prepararBye() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	n=enviar(soc, (char *)&b->blank, LENGTH_BLANK);
	if (n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-fin en 'prepararBye() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	n=enviar(soc, b->description, strlen(b->description)+1);
	if (n  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -3-fin en 'prepararBye() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -4-fin en 'prepararBye() de mensajes.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int leerBye(int soc, struct byeMessage *b, size_t resto){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'leerBye() de mensajes.c --\n");
	//return 1;
#endif
	ssize_t n;
	unsigned char code[LENGTH_BYE_CODE];
	char blank;

	b->description = malloc (resto-LENGTH_BYE_CODE-LENGTH_BLANK);
	if ((n=recibir(soc, code, LENGTH_BYE_CODE)) <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-fin en 'leerBye() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	memcpy ( b->code, code, LENGTH_BYE_CODE );
	if ((n=recibir(soc, (char *)&blank, LENGTH_BLANK))  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-fin en 'leerBye() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	b->blank = blank;
	if ((n=recibir(soc, b->description, resto-LENGTH_BYE_CODE-LENGTH_BLANK))  <= 0 ) {
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -3-fin en 'leerBye() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -4-fin en 'leerBye() de mensajes.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}


/*
 * antiormente se implementaron los mensajes propios
 * ahora se definen aquellos en los que interviene el sercivio HTTP
 */
void obtenerIPLocal(char *ipL){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'obtenerIPLocal() de mensajes.c --\n");
	//return 1;
#endif
	char hostname[MAXHOSTNAMELEN];
	struct hostent *h;
	char **aux;
	gethostname(hostname,sizeof(hostname));
	if ((h = gethostbyname(hostname))==NULL){
		h = gethostbyname("localhost");
	}
	aux = h->h_addr_list;
	inet_ntop(h->h_addrtype,*aux, ipL, sizeof(ipL));
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'obtenerIPLocal() de mensajes.c --\n");
	//return 1;
#endif
}

int pedirConexion(int soc){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'pedirConexion() de mensajes.c --\n");
	//return 1;
#endif
	int sal = B_TRUE;
	char *mens = NULL;
	int lon=strlen(BYE)+strlen(ROTELLA_CONNECT);
	lon+=strlen(USER_AGENT);
	lon+=(4*sizeof(CR));
	lon+=(3+4*sizeof(LF));
	lon+=2*sizeof(VERSION);
	lon+=2*sizeof(REVISION);
	mens = malloc(lon);
	sprintf(mens,"%s%s.%s%c%c%s%s.%s%c%c%s%c%c%c%c",ROTELLA_CONNECT,VERSION,REVISION,CR,LF,USER_AGENT,VERSION,REVISION,CR,LF,BYE,CR,LF,CR,LF);
	sal = send (soc, mens, strlen (mens), MSG_NOSIGNAL);
	free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'pedirConexion() de mensajes.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}

int enviarRespuestaServidor(int soc){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'enviarRespuestaServidor() de mensajes.c --\n");
	//return 1;
#endif
	int sal = B_TRUE;
	char *mens;
	int lon=strlen(BYE)+strlen(ROTELLA);
	lon+=strlen(EXITING_NORMALLY);
	lon+=strlen(USER_AGENT);
	lon+=4*sizeof(CR);
	lon+=7;
	lon+=4*sizeof(LF);
	lon+=2*sizeof(VERSION);
	lon+=2*sizeof(REVISION);
	mens = malloc(lon);
	sprintf(mens,"%s%s.%s %s OK%c%c%s%s.%s%c%c%s%c%c%c%c",ROTELLA,VERSION,REVISION,EXITING_NORMALLY,CR,LF,USER_AGENT,VERSION,REVISION,CR,LF,BYE,CR,LF,CR,LF);
	sal=send (soc, mens, strlen (mens), MSG_NOSIGNAL);
	free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'enviarRespuestaServidor() de mensajes.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}

int enviarRespuestaCliente(int soc){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'enviarRespuestaCliente() de mensajes.c --\n");
	//return 1;
#endif
	int sal = B_TRUE;
	char *mens;
	int lon=strlen(ROTELLA)+strlen(EXITING_NORMALLY);
	lon+=2*sizeof(CR);
	lon+=6;
	lon+=2*sizeof(LF);
	lon+=sizeof(VERSION);
	lon+=sizeof(REVISION);
	mens = malloc(lon);
	sprintf(mens,"%s%s.%s %s OK%c%c%c%c",ROTELLA,VERSION,REVISION,EXITING_NORMALLY,CR,LF,CR,LF);
	sal = send (soc, mens, strlen (mens), MSG_NOSIGNAL);
	free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'enviarRespuestaCliente() de mensajes.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}


int pedirArchivo (int soc, char *indiceArchivo, char *nombreArchivo){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'pedirArchivo() de mensajes.c --\n");
	//return 1;
#endif
	int sal = B_TRUE;
	char *mens;
	char ipL[INET_ADDRSTRLEN];
	int lon=0;
	obtenerIPLocal(ipL);
	lon+=strlen(GET); //GET
	lon+=strlen(SEPARADOR);
	lon+=strlen(indiceArchivo); //indiceArchivo
	lon+=strlen(nombreArchivo); //nombreArchivo
	lon+=4; // de '/' + '/' + '(espacio)' + ':'
	lon+=LENGTH_PUERTO_HTTP; //puertoLocal
	lon+=strlen(HTTP_V_R); //HTTP_V_R
	lon+=5*sizeof(CR); //CR,LF + CR,LF + CR,LF
	lon+=5*sizeof(LF); // + CR,LF,CR,LF
	lon+=strlen(USER_AGENT); //USER_AGENT
	lon+=strlen(HOST); //HOST
	lon+=strlen(CONNECTION_CLOSE); //CONNECTION_CLOSE
	lon+=strlen(ipL); //ip
	mens = malloc (lon);
	sprintf (mens,"%s/%s/%s %s%c%c%s%c%c%s%s:%d%c%c%s%c%c%c%c",GET,indiceArchivo,nombreArchivo,HTTP_V_R,CR,LF,USER_AGENT,CR,LF,HOST,ipL,puertoLocal,CR,LF,CONNECTION_CLOSE,CR,LF,CR,LF);
	sal = send (soc, mens, strlen (mens), MSG_NOSIGNAL);
	free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'pedirArchivo() de mensajes.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}

int responderPeticionArchivo (int soc, int indiceArchivo, char *estado, char *estadoMens); //respuesta a pet de archivo


int envioUpdateRequest(int soc){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'envioUpdateRequest() de mensajes.c --\n");
	//return 1;
#endif
	int sal = B_TRUE;
	char *mens;
	char ipL[INET_ADDRSTRLEN];
	int lon=0;
	obtenerIPLocal(ipL);
	lon+=strlen(GET); //GET,
	lon+=strlen(URLrowebcache); //URLrowebcache,
	lon+=7; //4+1+1+1: de '?ip=' + ':' + '(espacio)' + '.'
	lon+=LENGTH_PUERTO_HTTP; //puerto Local
	lon+=strlen(HTTP_V_R); //HTTP_V_R
	lon+=5*sizeof(CR);//CR,LF,,CR,LF,CR,LF
	lon+=5*sizeof(LF);//CR,LF, , CR,LF
	lon+=strlen(USER_AGENT); //USER_AGENT
	lon+=strlen(HOST); //HOST
	lon+=strlen(CONNECTION_CLOSE); //CONNECTION_CLOSE
	lon+=strlen(ipL); //ipL
	lon+=strlen(ipL); //,ipL
	lon+=sizeof(VERSION); //,VERSION
	lon+=sizeof(REVISION); //REVISION,
	mens = malloc (lon);
	sprintf (mens,"%s%s?ip=%s:%d %s%c%c%s%s.%s%c%c%s%s%c%c%s%c%c%c%c",GET,URLrowebcache,ipL,puertoLocal,HTTP_V_R,CR,LF,USER_AGENT,VERSION,REVISION,CR,LF,HOST,ipL,CR,LF,CONNECTION_CLOSE,CR,LF,CR,LF);
	sal = send (soc, mens, strlen (mens), MSG_NOSIGNAL);
	free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'envioUpdateRequest() de mensajes.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}

int envioHostfileRequest (int soc){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'envioHostfileRequest() de mensajes.c --\n");
	//return 1;
#endif
	ssize_t enviado;
	int sal = B_TRUE;
	char *mens;
	char ipL[INET_ADDRSTRLEN];
	int lon=0;
	obtenerIPLocal(ipL);
	lon+=strlen(GET);// GET
	lon+=strlen(URLrowebcache); //URLrowebcache
	lon+=3; // de '?' + '(espacio)' + '.'
	lon+=strlen(HTTP_V_R); //HTTP_V_R
	lon+=5*sizeof(CR); // CR,LF + CR,LF + CR,LF
	lon+=5*sizeof(LF); // CR,LF,CR,LF
	lon+=strlen(USER_AGENT); // USER_AGENT
	lon+=strlen(HOST); // HOST
	lon+=strlen(CONNECTION_CLOSE); // CONNECTION_CLOSE
	lon+=strlen("hostfile=1");
	lon+=strlen(ipL); // ipL
	lon+=sizeof(VERSION); // VERSION
	lon+=sizeof(REVISION); // REVISION
	mens = malloc (lon);
	sprintf (mens,"%s%s?hostfile=1 %s%c%c%s%s.%s%c%c%s%s%c%c%s%c%c%c%c",GET,URLrowebcache,HTTP_V_R,CR,LF,USER_AGENT,VERSION,REVISION,CR,LF,HOST,ipL,CR,LF,CONNECTION_CLOSE,CR,LF,CR,LF);
	enviado=enviar(soc, mens, strlen(mens));
	if (enviado<0) sal = B_FALSE;
	free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'envioHostfileRequest() de mensajes.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}

char * recibirCadena (int soc, size_t tam, char sep){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'recibirCadena() de mensajes.c --\n");
	//return 1;
#endif
	char *cad;
	char *sal = NULL;
	char *pos;
	char car;
	size_t i = 0;
	ssize_t leido;
	cad = malloc (tam+1);
	bzero ( cad, (tam+1) );
	pos = cad;
	leido=recibir(soc, (char *)&car, 1);
	while ( car != sep && leido > 0 && i < tam) {
		memcpy(pos,&car,1);
		pos++;
		i++;
		leido=recibir(soc, (char *)&car, 1);
	}
	if ( leido > 0 ){
		sal = malloc (strlen (cad)+1);
		bzero (sal, strlen (cad)+1);
		memcpy (sal, cad, strlen(cad));
	}
	if (cad) free(cad);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'recibirCadena() de mensajes.c, salida=%s --\n", sal);
	//return 1;
#endif
	return sal;

}

int recibirRespuestaConexion (int soc){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'recibirRespuestaConexion() de mensajes.c --\n");
	//return 1;
#endif
	char *mens = NULL;
	mens = recibirCadena(soc,TAM_MAX_PAR,LF);
	if (strncmp(mens,ROTELLA_CONNECT, strlen(ROTELLA_CONNECT))!=0){
		free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'recibirRespuestaConexion() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	free (mens);
	mens = recibirCadena(soc, TAM_MAX_PAR, LF);
	if (strncmp(mens,"User-Agent", strlen("User-Agent"))!=0){
		free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-Fin en 'recibirRespuestaConexion() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	free(mens);
	mens = recibirCadena(soc, TAM_MAX_PAR,LF);
	if (strncmp(mens,BYE, strlen(BYE))!=0){
		free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -3-Fin en 'recibirRespuestaConexion() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
//TODO aqui hay q comprobar el valor de la cabecera BYE para saber si el nodo q intenta conectarse
	//admite BYE
	free(mens);
	mens = recibirCadena (soc,TAM_MAX_PAR,LF);
	while(mens!=NULL && strlen(mens)!=2 && mens[0]!=CR && mens[1]!=LF){
		free(mens);
		mens = recibirCadena (soc,TAM_MAX_PAR,LF);
	}
	free(mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -4-Fin en 'recibirRespuestaConexion() de mensajes.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int recibirRespuestaServidor(int soc){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'recibirRespuestaServidor() de mensajes.c --\n");
	//return 1;
#endif
	char *mens = NULL;
	mens = recibirCadena(soc,strlen(ROTELLA)+2+sizeof(VERSION)+sizeof(REVISION),' ');
	if (strncmp(mens,ROTELLA, strlen(ROTELLA))!=0){
		free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'recibirRespuestaServidor() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	free (mens);
	mens = recibirCadena(soc, strlen(EXITING_NORMALLY), LF);
	if (mens !=NULL || mens[0]!='2'){
		free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-Fin en 'recibirRespuestaServidor() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	free(mens);
	mens = recibirCadena(soc, TAM_MAX_PAR, LF);
	//se termina de leer la cadena
	while(mens!=NULL && strlen(mens)!=2 && mens[0]!=CR && mens[1]!=LF){
		free(mens);
		mens = recibirCadena (soc,TAM_MAX_PAR,LF);
	}
	free(mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -3-Fin en 'recibirRespuestaServidor() de mensajes.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int recibirRespuestaCliente(int soc){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'recibirRespuestaCliente() de mensajes.c --\n");
	//return 1;
#endif
	char *mens = NULL;
	mens = recibirCadena(soc,strlen(ROTELLA)+2+sizeof(VERSION)+sizeof(REVISION),' ');
	if (strncmp(mens,ROTELLA, strlen(ROTELLA))!=0){
		free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'recibirRespuestaCliente() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	free (mens);
	mens = recibirCadena(soc, strlen(EXITING_NORMALLY), LF);
	if (mens ==NULL || mens[0]!='2'){
		free (mens);
		return B_FALSE;
	}
	free(mens);
	mens = recibirCadena(soc, TAM_MAX_PAR, LF);
	while(mens!=NULL && strlen(mens)!=2 && mens[0]!=CR && mens[1]!=LF){
		free(mens);
		mens = recibirCadena (soc,TAM_MAX_PAR,LF);
	}
	free(mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-Fin en 'recibirRespuestaCliente() de mensajes.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int recibirGetMessage (int soc, char *nombreArchivo){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'recibirGetMessage() de mensajes.c --\n");
	//return 1;
#endif
	char *mens = NULL;
	mens = recibirCadena(soc,strlen(HTTP_V_R),' ');
	if (strncmp (mens,HTTP_V_R,strlen(HTTP_V_R))!= 0){
		free(mens);
		close (soc);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'recibirGetMessage() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}

	free (mens);
	mens = recibirCadena(soc,strlen(EXITING_NORMALLY),' ');
	if ( mens[0] != '2' ){
		free(mens);
		close (soc);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-Fin en 'recibirGetMessage() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	free (mens);
	mens = recibirCadena(soc,TAM_MAX_LINEA,LF);
	while (strlen(mens)!=2 && mens[0]!=CR){
		free (mens);
		mens = recibirCadena(soc,TAM_MAX_LINEA,LF);
	}

	if (mens!=NULL) free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -3-Fin en 'recibirGetMessage() de mensajes.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int recibirRespuestaUpdate(int soc){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'recibirRespuestaUpdate() de mensajes.c --\n");
	//return 1;
#endif
	char * mens;
	int sal = B_FALSE;
	mens = recibirCadena(soc,strlen(HTTP_V_R),' ');
	if (strncmp (mens,HTTP_V_R,strlen(HTTP_V_R))== 0){ //si es HTTP_V_R
		free (mens);
		mens = recibirCadena(soc,strlen(EXITING_NORMALLY),' '); //si el cod es 200
		if ( mens[0] == '2' ){
			free (mens);
			mens = recibirCadena(soc,TAM_MAX_LINEA,LF);
			while (strlen(mens)!=2 && mens[0]!=CR){
				free (mens);
				mens = recibirCadena(soc,TAM_MAX_LINEA,LF);
			}
			free (mens);
			mens = recibirCadena(soc,TAM_MAX_LINEA,LF);
			while (mens != NULL){
				if (strstr(mens,OK)!=NULL){
					sal = B_TRUE;
				}
				free (mens);
				mens = recibirCadena(soc,TAM_MAX_PAR,LF);
			}
		}else{
			sal = B_FALSE;
		}
	}else{
		sal = B_FALSE;
	}
	if (sal == B_FALSE)
		close (soc);
	if (mens!=NULL) free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'recibirRespuestaUpdate() de mensajes.c, salida=%i --\n", sal);
	//return 1;
#endif
	return sal;
}


int recibirRespuestaHostfileRequest (int soc){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'recibirRespuestaHostfileRequest() de mensajes.c --\n");
	//return 1;
#endif
	char * mens;
	int i=0;
	int j=0;
	in_addr_t ip;
	unsigned int puerto;
	char host_ip[MAXHOSTNAMELEN];
	char host_puerto[6];
	char hostname[MAXHOSTNAMELEN];
	struct hostent *h;
	struct serventNode *nodo;
	struct sockaddr_in servidor;

	mens = recibirCadena(soc,strlen(HTTP_V_R),' ');
	if (strncmp (mens,HTTP_V_R,strlen(HTTP_V_R))!= 0){
		if (mens) free (mens);
		close (soc);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'recibirRespuestaHostfileRequest() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
	free (mens);
	mens = recibirCadena(soc,strlen(EXITING_NORMALLY),' ');
	if ( mens[0] == '2' ){
		free (mens);
		mens = recibirCadena(soc,TAM_MAX_LINEA,LF);
		while (strlen(mens)!=2 && mens[0]!=CR){
			free (mens);
			mens = recibirCadena(soc,TAM_MAX_LINEA,LF);
		}
		free (mens);
		mens = recibirCadena(soc,TAM_MAX_LINEA,LF);
		while (mens != NULL){
			if (index(mens,':')!=NULL){
				bzero(host_ip,MAXHOSTNAMELEN);
				for ( i = 0; i < strlen(mens) && mens[i]!=':'; ++i)	host_ip[i]=mens[i];
				host_ip[i+1]='\0';
				j = 0;
				for ( i = i + 1 ; i < strlen(mens) && mens[i]!=CR; ++i, ++j )host_puerto[j] = mens[i];
				host_puerto[j] = '\0';
				puerto = atoi (host_puerto);
				bzero (&servidor, sizeof (struct sockaddr));
				servidor.sin_family = AF_INET;
				servidor.sin_port = htons (puerto);
				inet_pton(AF_INET, host_ip, &servidor.sin_addr);
				gethostname(hostname,sizeof(hostname));
				if ((h = gethostbyname(hostname))==NULL){
					h = gethostbyname("localhost");
				}
				memcpy(&ip,h->h_addr,sizeof(ip));
				if (memcmp(&servidor.sin_addr,&ip, sizeof(ip))!=0 ){
					nodo = malloc (sizeof (struct serventNode));
					memcpy (&(nodo->addr), &servidor, sizeof (struct sockaddr_in));
					insertNodoCache(nodo);
				}
			}
			free (mens);
			mens = recibirCadena(soc,TAM_MAX_PAR,LF);
		}
	}else if ( mens[0]=='3'){
		printf("FALLO en la conexion, redirigirla \n");
	}else{
		if (mens) free (mens);
		close (soc);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-Fin en 'recibirRespuestaHostfileRequest() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}

	if (mens) free (mens);
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -3-Fin en 'recibirRespuestaHostfileRequest() de mensajes.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}

int mensajeExpirado(struct message* m){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t --Inicio en 'mensajeExpirado() de mensajes.c --\n");
	//return 1;
#endif
	if( m->header->ttl > 15 ) return B_TRUE;
	if( m->header->ttl + m->header->hops > MAX_SALTOS )	m->header->ttl = MAX_SALTOS - m->header->hops;
	m->header->ttl = m->header->ttl-1;
	m->header->hops = m->header->hops + 1;
	if( m->header->ttl > 0 ){
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -1-Fin en 'mensajeExpirado() de mensajes.c, salida=%i --\n", B_FALSE);
	//return 1;
#endif
		return B_FALSE;
	}
#ifdef DEBUG_MENSAJE
	fprintf(stderr,"\t -2-Fin en 'mensajeExpirado() de mensajes.c, salida=%i --\n", B_TRUE);
	//return 1;
#endif
	return B_TRUE;
}




